﻿using System;
using System.Text;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MIMSDomain.Entities;
using MIMSDomain.Abstract;
using Moq;
using System.Linq;

namespace MIMSUnitTests.Domain
{
    /// <summary>
    /// Summary description for EFMedicalPersonnelTests
    /// </summary>
    [TestClass]
    public class EFMedicalPersonnelTests
    {
        public readonly IRepository<MedicalPersonnel> MockMedicalPersonnelRepository;

         public EFMedicalPersonnelTests()
        {
            //Arrange
            var _MedicalPersonnels = new List<MedicalPersonnel>{
                new MedicalPersonnel{Id=1, FirstName="ABC", MiddleName="Kester", LastName="ROC", Sex ="M"  ,Code="536", MedicalPersonnelType= MedicalPersonnelType.Doctor  },
                new MedicalPersonnel{Id=2, FirstName="CDE",MiddleName="Kester", LastName="ROC", Sex ="M"  ,Code="537", MedicalPersonnelType= MedicalPersonnelType.Doctor  },
                new MedicalPersonnel{Id=3, FirstName="EDF",MiddleName="Kester", LastName="ROC", Sex ="M"  ,Code="538", MedicalPersonnelType= MedicalPersonnelType.Doctor  },
                new MedicalPersonnel{Id=4, FirstName="GHI",MiddleName="Kester", LastName="ROC", Sex ="M"  ,Code="539", MedicalPersonnelType= MedicalPersonnelType.Doctor  }
            };

            //Mock the  Repository
            var target = new Mock<IRepository<MedicalPersonnel>>();
            target.Setup(p => p.All).Returns(_MedicalPersonnels.AsQueryable());

            target.Setup(p => p.GetById(It.IsAny<int>())).Returns((int i) =>
                _MedicalPersonnels.Where(p => p.Id == i).Single());
            target.Setup(p => p.Save(It.IsAny<MedicalPersonnel>())).Returns((MedicalPersonnel obj) =>
                {
                    if (obj.Id.Equals(default(int)))
                    {
                        obj.Id = _MedicalPersonnels.Count() + 1;
                        _MedicalPersonnels.Add(obj);
                    }
                    else
                    {
                        var original = _MedicalPersonnels.Where(p => p.Id == obj.Id).Single();
                        if (original == null)
                        {
                            return false;
                        }
                        original.FirstName = obj.FirstName;
                        original.MiddleName = obj.MiddleName;
                        original.LastName = obj.LastName;
                        original.Sex = obj.Sex;
                        original.MedicalPersonnelType = obj.MedicalPersonnelType;
                        
                    }
                    return true;
                });
            target.Setup(p => p.Delete(It.IsAny<MedicalPersonnel>())).Returns((MedicalPersonnel obj) =>
                {

                    if (_MedicalPersonnels.Contains(obj))
                    {
                        _MedicalPersonnels.Remove(obj);
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                });
            
            MockMedicalPersonnelRepository = target.Object;
        }
        
        [TestMethod]
        public void CanSave()
        {
            //Arrange
            var count = MockMedicalPersonnelRepository.All.Count();
            //Assert
            Assert.AreEqual(4, count); //Confirm  count
            //Act
            var expected = MockMedicalPersonnelRepository.Save(new MedicalPersonnel { FirstName = "ROC", MiddleName="Solomon",LastName="Folorunsho",Sex="M", Code="539", MedicalPersonnelType= MedicalPersonnelType.Doctor });

            //Assert
            count = MockMedicalPersonnelRepository.All.Count();
            Assert.AreEqual(5, count); //Confirm  count after saving

        }

        [TestMethod]
        public void CannotAddDuplicate()
        {
            //Arrange
            var count = MockMedicalPersonnelRepository.All.Count();
            //Assert
            Assert.AreEqual(4, count); //Confirm  count
            //Act
            var expected = MockMedicalPersonnelRepository.Save(new MedicalPersonnel { FirstName = "ROC", MiddleName = "Solomon", LastName = "Folorunsho", Sex = "M", Code = "540", MedicalPersonnelType = MedicalPersonnelType.Doctor });

            //Assert
            count = MockMedicalPersonnelRepository.All.Count();
            Assert.AreEqual(5, count); //Confirm  count after saving
        }

        [TestMethod]
        public void CanGetById()
        {
            //Act
            var expected = MockMedicalPersonnelRepository.GetById(3);
            //Assert
            Assert.IsNotNull(expected);
            Assert.IsInstanceOfType(expected, typeof(MedicalPersonnel));
            Assert.AreEqual(expected.Code, "538");
        }

        [TestMethod]
        public void CanGetAll()
        {
            //Act
            var expected = MockMedicalPersonnelRepository.All;
            //Assert
            Assert.IsNotNull(expected);
            Assert.IsInstanceOfType(expected, typeof(IQueryable<MedicalPersonnel>));
            Assert.AreEqual(expected.Count(), 4);
        }

        [TestMethod]
        public void CanDelete()
        {
            //Arrange
            var count = MockMedicalPersonnelRepository.All.Count();
            Assert.AreEqual(4, count);
            var objAllergy = MockMedicalPersonnelRepository.GetById(3);
            Assert.IsInstanceOfType(objAllergy, typeof(MedicalPersonnel));
            //Act
            MockMedicalPersonnelRepository.Delete(objAllergy);
            count = MockMedicalPersonnelRepository.All.Count();
            //Assert
            Assert.AreEqual(3, count);
        }
        
    }
}
